LinuxCommandLibrary

]]

Conditional evaluation within shell scripts

TLDR

View documentation for the [[ keyword

$ tldr [[
copy

SYNOPSIS

Since ]] is not a standalone command but a shell keyword closing a compound command, it does not have an independent synopsis. Its usage is strictly as the closing part of the [[ ... ]] construct:

[[ expression ]]

The expression within the brackets is evaluated, and the exit status of the [[ ... ]] command indicates whether the expression is true (0) or false (1).

PARAMETERS

No direct parameters
    The ]] keyword itself does not accept any parameters. Its function is solely to terminate the conditional expression initiated by [[. All operators and operands are part of the expression contained between [[ and ]].

Common operators used within [[ ... ]]:
    While not parameters of ]], the following are common test operators and constructs used within the expression that ]] closes:
-a file: True if file exists.
-d file: True if file is a directory.
-f file: True if file is a regular file.
-z string: True if string has zero length.
-n string: True if string has non-zero length.
string1 = string2: True if string1 is equal to string2.
string1 != string2: True if string1 is not equal to string2.
integer1 -eq integer2: True if integer1 is equal to integer2.
integer1 -ne integer2: True if integer1 is not equal to integer2.
integer1 -gt integer2: True if integer1 is greater than integer2.
integer1 -ge integer2: True if integer1 is greater than or equal to integer2.
integer1 -lt integer2: True if integer1 is less than integer2.
integer1 -le integer2: True if integer1 is less than or equal to integer2.
string =~ regex: True if string matches regex (Bash/Zsh only).
expr1 && expr2: Logical AND.
expr1 || expr2: Logical OR.

DESCRIPTION

The double closing square bracket, ]], is not a standalone Linux command or executable program. Instead, it serves as the mandatory closing delimiter for the [[ ... ]] compound command in Bash, KornShell (ksh), and Zsh. This construct is an enhanced version of the older [ ... ] (which is an alias for the test command) used for evaluating conditional expressions in shell scripts.

The [[ ... ]] syntax offers several advantages over [ ... ], including the prevention of word splitting and pathname expansion, and native support for logical operators like && (AND) and || (OR), as well as regular expression matching with =~. Because [[ and ]] are shell keywords rather than external commands, they provide a more robust and less error-prone way to perform conditional checks. Therefore, ]] only has meaning when paired with an opening [[, forming a complete conditional expression.

CAVEATS

]] cannot be used on its own; it always requires a preceding [[ to form a valid construct.
There must be a space before the closing ]] (e.g., [[ expression ]], not [[ expression]]).
The [[ ... ]] construct, and thus ]], is a Bash/KornShell/Zsh keyword and is not part of the POSIX standard for sh. Scripts using it may not be portable to all Bourne-like shells.

WHY PREFER <B><I>[[ ... ]]</I></B> OVER <B><I>[ ... ]</I></B>?

Using [[ ... ]] (and thus ]]) is generally recommended in Bash scripts for several reasons:
No word splitting/pathname expansion: Variables inside [[ ... ]] do not need to be quoted (though it's good practice), as the shell does not perform word splitting or pathname expansion on them. This significantly reduces quoting errors.
Regular expression matching: It supports the =~ operator for powerful regular expression pattern matching.
Logical operators: It allows direct use of && (AND) and || (OR) operators within the expression, simplifying complex conditions without needing multiple [ ... ] commands.
Type-safe comparisons: String and numeric comparisons are handled more predictably without requiring explicit type conversion for numeric strings.

HISTORY

The [[ ... ]] construct, which ]] completes, originated in the KornShell (ksh) to address limitations and common pitfalls of the traditional [ ... ] (test) command. It was subsequently adopted by Bash (version 2.0 and later) and Zsh, becoming a widely used feature for more robust and readable conditional expressions in shell scripting. Its status as a shell keyword, rather than an external command, allows for more advanced parsing and fewer issues with word splitting and globbing.

SEE ALSO

[(1) (test command), test(1), bash(1), ksh(1), zsh(1), if(1)

Copied to clipboard